﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System.ComponentModel;
using NetJsWire.JsonRpcHandler;
using NetJsWire.Widgets.Ui.Layout;

namespace NetJsWire.Widgets.Config
{
    public class ContainerConfigOptions : BoxComponentConfigOptions
    {
        private object _activeItem;

        private bool _autoDestroy = true;

        private string _bubbleEvents = "['add', 'remove']";

        private int? _bufferResize;

        private string _defaults;

        private bool _forceLayout;

        private bool _hideBorders;
        private LayoutType _layout = LayoutType.Auto;
        private string _layoutConfig;

        private bool? _monitorResize;

        private string _resizeEvent = "resize";

        public ContainerConfigOptions( IWidget ownerWidget )
            : base( ownerWidget )
        { }

        /// <summary>
        ///   A string component id or the numeric index of the component that should be initially activated within the container's layout on render. 
        ///   For example, <c>activeItem: 'item-1'</c> or <c>activeItem: 0</c> (index 0 = the first item in the container's collection).
        ///   <remarks>
        ///     activeItem only applies to layout styles that can display items one at a time (like Ext.layout.AccordionLayout, Ext.layout.CardLayout and 
        ///     Ext.layout.FitLayout). Related to Ext.layout.ContainerLayout.activeItem.
        ///   </remarks>
        /// </summary>
        [Description( "A string component id or the numeric index of the component that should be initially activated within the container's layout on render." )]
        [DefaultValue( null )]
        [Browsable( true )]
        [TypeConverter( typeof( StringConverter ) )]
        public override object ActiveItem
        {
            get { return _activeItem; }
            set
            {
                SetValue( "activeItem", value, null, _activeItem );
                _activeItem = value;
            }
        }

        /// <summary>
        ///   If true the container will automatically destroy any contained component that is removed from it, else destruction must be handled manually (defaults to true).
        /// </summary>
        [Description( "If true the container will automatically destroy any contained component that is removed from it, else destruction must be handled manually (defaults to true)." )]
        [DefaultValue( true )]
        [Browsable( true )]
        public override bool AutoDestroy
        {
            get { return _autoDestroy; }
            set
            {
                SetValue( "autoDestroy", value, true, _autoDestroy );
                _autoDestroy = value;
            }
        }

        /// <summary>
        ///   An array of events that, when fired, should be bubbled to any parent container.
        /// </summary>
        [Description( "An array of events that, when fired, should be bubbled to any parent container." )]
        [DefaultValue( "['add', 'remove']" )]
        [Browsable( true )]
        public override string BubbleEvents
        {
            get { return _bubbleEvents; }
            set
            {
                SetValue( "bubbleEvents", value, "['add', 'remove']", _bubbleEvents );
                _bubbleEvents = value;
            }
        }

        /// <summary>
        ///   When set to true (50 milliseconds) or a number of milliseconds, the layout assigned for this container will buffer the frequency it calculates and does a re-layout of components.
        ///   This is useful for heavy containers or containers with a large quantity of sub-components for which frequent layout calls would be expensive. Defaults to 50.
        /// </summary>
        [Description( "When set to true (50 milliseconds) or a number of milliseconds, the layout assigned for this container will buffer the frequency it calculates and does a re-layout of components." )]
        [DefaultValue( null )]
        [Browsable( true )]
        public override int? BufferResize
        {
            get { return _bufferResize; }
            set
            {
                SetValue( "bufferResize", value, null, _bufferResize );
                _bufferResize = value;
            }
        }

        /// <summary>
        ///   This option is a means of applying default settings to all added items whether added through the items config or via the add or insert methods.
        ///   If an added item is a config object, and not an instantiated Component, then the default properties are unconditionally applied. If the added item
        ///   is an instantiated Component, then the default properties are applied conditionally so as not to override existing properties in the item.
        ///   If the defaults option is specified as a function, then the function will be called using this Container as the scope (this reference) and passing 
        ///   the added item as the first parameter. Any resulting object from that call is then applied to the item as default properties.
        ///   For example, to automatically apply padding to the body of each of a set of contained Ext.Panel items, you could pass: <c>defaults: {bodyStyle:'padding:15px'}.</c>
        ///   <example>
        ///     <code>
        ///       defaults: {               // defaults are applied to items, not the container
        ///       autoScroll:true
        ///       },
        ///       items: [
        ///       {
        ///       xtype: 'panel',   // defaults do not have precedence over
        ///       id: 'panel1',     // options in config objects, so the defaults
        ///       autoScroll: false // will not be applied here, panel1 will be autoScroll:false
        ///       },
        ///       new Ext.Panel({       // defaults do have precedence over options
        ///       id: 'panel2',     // options in components, so the defaults
        ///       autoScroll: false // will be applied here, panel2 will be autoScroll:true.
        ///       })
        ///       ]
        ///     </code>
        ///   </example>
        /// </summary>
        [Description( "This option is a means of applying default settings to all added items whether added through the items config or via the add or insert methods." )]
        [DefaultValue( null )]
        [Browsable( true )]
        public override string Defaults
        {
            get { return _defaults; }
            set
            {
                SetValue( "defaults", value, null, _defaults );
                _defaults = value;
            }
        }

        /// <summary>
        ///   If true the container will force a layout initially even if hidden or collapsed.
        ///   This option is useful for forcing forms to render in collapsed or hidden containers. (defaults to false).
        /// </summary>
        [Description( "If true the container will force a layout initially even if hidden or collapsed." )]
        [DefaultValue( false )]
        [Browsable( true )]
        public override bool ForceLayout
        {
            get { return _forceLayout; }
            set
            {
                SetValue( "forceLayout", value, false, _forceLayout );
                _forceLayout = value;
            }
        }

        /// <summary>
        ///   True to hide the borders of each contained component, false to defer to the component's existing border settings (defaults to false).
        /// </summary>
        [Description( "True to hide the borders of each contained component, false to defer to the component's existing border settings (defaults to false)." )]
        [DefaultValue( false )]
        [Browsable( true )]
        public override bool HideBorders
        {
            get { return _hideBorders; }
            set
            {
                SetValue( "forceLayout", value, false, _hideBorders );
                _hideBorders = value;
            }
        }

        /// <summary>
        ///   True to automatically monitor window resize events to handle anything that is sensitive to the current size of the viewport.
        ///   <remarks>
        ///     This value is typically managed by the chosen layout and should not need to be set manually.
        ///   </remarks>
        /// </summary>
        [Description( "True to automatically monitor window resize events to handle anything that is sensitive to the current size of the viewport." )]
        [DefaultValue( null )]
        [Browsable( true )]
        public override bool? MonitorResize
        {
            get { return _monitorResize; }
            set
            {
                SetValue( "monitorResize", value, null, _monitorResize );
                _monitorResize = value;
            }
        }

        /// <summary>
        ///   The event to listen to for resizing in layouts. Defaults to 'resize'.
        /// </summary>
        [Description( "The event to listen to for resizing in layouts. Defaults to 'resize'." )]
        [DefaultValue( "resize" )]
        [Browsable( true )]
        public override string ResizeEvent
        {
            get { return _resizeEvent; }
            set
            {
                SetValue( "resizeEvent", value, "resize", _resizeEvent );
                _resizeEvent = value;
            }
        }

        /// <summary>
        ///   The layout type to be used for this container.
        ///   <remarks>
        ///     <b>*Important:</b> In order for child items to be correctly sized and positioned, typically a layout manager must be specified through the layout configuration option.
        ///   </remarks>
        ///   The sizing and positioning of child items is the responsibility of the Container's layout manager which creates and manages the type of layout you have in mind.
        ///   For example:
        ///   <example>
        ///     <code>
        ///       new Ext.Window({
        ///       width:300, height: 300,
        ///       layout: 'fit', // explicitly set layout manager: override the default (layout:'auto')
        ///       items: [{
        ///       title: 'Panel inside a Window'
        ///       }]
        ///       }).show();
        ///     </code>
        ///   </example>
        ///   If the layout configuration is not explicitly specified for a general purpose container (e.g. Container or Panel) the default layout manager will be used 
        ///   which does nothing but render child components sequentially into the Container (no sizing or positioning will be performed in this situation).
        ///   Some container classes implicitly specify a default layout (e.g. FormPanel specifies layout:'form'). Other specific purpose classes internally 
        ///   specify/manage their internal layout (e.g. GridPanel, TabPanel, TreePanel, Toolbar, Menu, etc.).
        /// </summary>
        [Description( "The layout type to be used for this container." )]
        [DefaultValue( LayoutType.Auto )]
        [Browsable( true )]
        public override LayoutType Layout
        {
            get { return _layout; }
            set
            {
                SetValue( "layout", value, LayoutType.Auto, _layout );
                _layout = value;
            }
        }

        /// <summary>
        ///   This is a config object containing properties specific to the chosen <see cref = "Layout" /> if <see cref = "Layout" /> has been specified as a string.
        /// </summary>
        [Description( "This is a config object containing properties specific to the chosen layout if layout has been specified as a string." )]
        [DefaultValue( ( string ) null )]
        [Browsable( true )]
        public override string LayoutConfig
        {
            get { return _layoutConfig; }
            set
            {
                SetValue( "layoutConfig", value, null, _layoutConfig );
                _layoutConfig = value;
            }
        }
    }
}
